// ==UserScript==
// @name           Yahoo Baseball Grab Player After Waivers Clear
// @namespace      http://glenncarr.com/greasemonkey/fantasybaseball
// @include        *baseball.fantasysports.yahoo.com/*/addplayer*
// @description    Allows you to automatically grab a player from the free agent pool as soon as he clears waivers
// @author         Glenn Carr (glenn at glenncarr dot com)
// $LastChangedRevision: 295 $
// $LastChangedDate: 2007-08-24 05:09:59 +0000 (Fri, 24 Aug 2007) $
// ==/UserScript==

(function(){

var waiverNote = document.getElementById( 'waivernote' );
if ( !waiverNote )
    return;
    
if ( !/waiver claim/i.test( waiverNote.innerHTML ) )
    return;
    
var table = document.getElementById( 'statTable0' );
if ( !table )
    return;

var addDropForm = document.forms.namedItem( 'yspglobalform' );
if ( !addDropForm )
    return;

var addButton = addDropForm.elements.namedItem( 'submit_add_drop' );
if ( !addButton )
    return;
    
if ( !/add this player/i.test( addButton.value ) )
    return;

String.prototype.stripTags = function() {
  return this.replace(/<\/?[^>]+>/gi,'');
}

var addPlayerUrl = null;
var addPlayerName = null;
for ( var iRow = 0; iRow < table.rows.length; iRow++ )
{
    var row = table.rows[ iRow ];
    if ( /^th$/i.test( row.cells[ 0 ].tagName ) )
        continue;

    for ( var iCell = 0; iCell < row.cells.length; iCell++ )
    {
        var cell = row.cells[ iCell ];
        var cellClass = cell.getAttribute( "class" );
        
        if ( /^player/i.test( cellClass ) )
        {
            var a = cell.getElementsByTagName( 'a' )[ 0 ];
            // Example: http://baseball.fantasysports.yahoo.com/b1/340204/addplayer?apid=5708
            addPlayerUrl = location.href.replace( /\/addplayer$/i, '' ) + '/addplayer?apid=' + a.href.replace( /^.+players\/(\d+)/i, '$1' );
            addPlayerName = a.innerHTML;
            break;
        }
    }
    break;
}

if ( !addPlayerUrl )
    return;
    
var WORKING_IMG_URL = "data:image/gif,GIF89a%0A%00%0A%00%91%03%00%CC%CC%CC%FFff%FF%00%00%FF%FF%FF!%FF%" +
"0BNETSCAPE2.0%03%01%00%00%00!%F9%04%05%00%00%03%00%2C%00%00%00%00%0A%00%0A%00%00%02%17%9C'r%06%80%1A%" +
"02s'%AE%3Bqk%9A%E2%C3%81%14Gz%D9Q%00%00!%F9%04%05%00%00%03%00%2C%01%00%00%00%08%00%03%00%00%02%0A%9C%" +
"136%22%83%03%00S%10%14%00!%F9%04%05%00%00%03%00%2C%00%00%00%00%06%00%06%00%00%02%0C%9C%070%11%A8%7C%A" +
"2%11%22%D2X%00%00!%F9%04%05%00%00%03%00%2C%00%00%01%00%03%00%08%00%00%02%0A%1C%608%13%C1%BE%96%10c%16" +
"%00!%F9%04%05%00%00%03%00%2C%00%00%04%00%06%00%06%00%00%02%0A%04%86c%C9%1C%E1%A0%10l%16%00!%F9%04%05%" +
"00%00%03%00%2C%01%00%07%00%08%00%03%00%00%02%0A%04%86%23b%13%A1Dz%A9%00%00!%F9%04%05%00%00%03%00%2C%0" +
"4%00%04%00%06%00%06%00%00%02%0C%9C'r%A8%BB%11%06%00%03Jz%0A%00!%F9%04%09%00%00%03%00%2C%07%00%01%00%0" +
"3%00%08%00%00%02%0A%94f%A3%1A1%BD%00%18r%14%00%3B";

var watchButton = document.createElement( 'input' );
watchButton.type = 'button';
watchButton.setAttribute( "class", "button" );
addButton.parentNode.insertBefore( watchButton, addButton );
watchButton.parentNode.insertBefore( document.createTextNode( ' ' ), watchButton.nextSibling );

var divStatus = document.createElement( 'div' );
divStatus.id = 'gncStatus';
var divButtonBar = document.getElementById( 'buttonbar' );
divButtonBar.parentNode.insertBefore( divStatus, divButtonBar.nextSibling );

GM_addStyle( '\
#gncStatus { padding: 5px 10px; font-size: 90%; font-weight: bold; } \
.gncTimestamp { font-style: italic; font-weight: normal } \
' );


initWatchButton();

function initWatchButton()
{
    watchButton.value = 'Add this player after clearing waivers';
    watchButton.addEventListener( 'click', startPlayerWatch, false );
}

function startPlayerWatch( e ) 
{
    divStatus.innerHTML = '';
    watchButton.value = "Cancel watch";
    watchButton.removeEventListener( 'click', startPlayerWatch, false );
    watchButton.addEventListener( 'click', function(e) { 
        divStatus.innerHTML = getTimestamp() + ' ' + 'Watch cancelled.';
        initWatchButton(); 
        }, false );
    watchPlayer( addPlayerUrl );
}

var MIN_DELAY_SECS = (60 * 15);
var MAX_DELAY_SECS = (60 * 20);

var userAgents = new Array( 
     'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
    ,'Opera/7.x (Windows NT 5.1; U) [en]'
    ,'Mozilla/5.0 (Windows; U; Win98; en-US; rv:0.9.2) Gecko/20010726 Netscape6/6.1'
    ,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6'
    ,'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TheFreeDictionary.com; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)' );
    
function watchPlayer()
{
    if ( !/cancel/i.test( watchButton.value ) )
        return;

    var userAgent = userAgents[ Math.floor( Math.random()*userAgents.length ) ];

    divStatus.innerHTML = getTimestamp() + ' ' + 'Getting status for ' + addPlayerName + '...';
    GM_xmlhttpRequest({
        method: 'GET',
        url: addPlayerUrl,
        headers: { 'User-Agent': userAgent },
        onload: function( responseDetails )
        {
            var delaySeconds = (MIN_DELAY_SECS+Math.floor(Math.random()*(MAX_DELAY_SECS-MIN_DELAY_SECS)));
            if ( responseDetails.status != 200 )
            {
                divStatus.innerHTML = getTimestamp() + ' ' + 'Unable to retrieve player status for ' + addPlayerName + ': ' + responseDetails.statusText;
                delaySeconds = 60 * 90; // Wait quite a while if there's an error
            }
            else
            {
                var match = responseDetails.responseText.replace( /[\r\n]/g, '' ).match( /waiver claim will be reflected on your lineup for (?:<[^>]+>)?[a-z]+, \D{3} (\d+)/i );
                if ( !match )
                {
                    alert( 'Unable to determine the date the player clears waivers.' );
                    return;
                }

                // ??? There's not a good way to determine the date on which the player will clear waivers
                /*                
                var clearDay = parseInt( match[ 1 ], 10 );
                var now = new Date();
                if ( now.getDate() != clearDay )
                {
                    divStatus.innerHTML = getTimestamp() + ' Waiting until tomorrow to check player status...';
                    delaySeconds = 60 * 120; // Wait quite a while before we check again
                }
                else
                */
                {
                    var delayMinutes = Math.round( delaySeconds / 60 );
                    if ( /waiver claim will be reflected on your lineup/i.test( responseDetails.responseText.replace( /[\r\n]/g, '' ) ) )
                    {
                        divStatus.innerHTML = getTimestamp() + ' ' + addPlayerName + ' is still on waivers, checking again in ' + delayMinutes + ' minutes... <img src="' + WORKING_IMG_URL + '" />';
                    }
                    else
                    if ( /transaction will be reflected on your lineup/i.test( responseDetails.responseText.replace( /[\r\n]/g, '' ) ) )
                    {
                        divStatus.innerHTML = getTimestamp() + ' ' + addPlayerName + ' has cleared waivers.';
                        addDropForm.submit();
                        return;
                    }
                    else
                    {
                        divStatus.innerHTML = getTimestamp() + ' Unable to claim ' + addPlayerName + ' from waivers.';
                        return;
                    }
                }
            }
            window.setTimeout( watchPlayer, delaySeconds * 1000 );

        },});
}

function getTimestamp()
{
    return '<span class="gncTimestamp">' + ( new Date() ) + '</span> ';
}

})();